#ifndef LEONARDVIRTUALMACHINE_H
#define LEONARDVIRTUALMACHINE_H
#include "Expression.h"
#include "CopyPointer.h"
#include "AutoPointer.h"
#include "Context.h"
#include <stack>
#include <string>
#include "Pattern.h"
#include "TemplatePattern.cpp"

class LeonardVirtualMachine {
public:
	LeonardVirtualMachine() : context(new Context("Global")) {
		registerFunction(context.get());
	}

	AutoPointer<TreeExpression::Expression> top() { return stack_operand.top(); }
	void pop() { stack_operand.pop(); }
	void push(AutoPointer<TreeExpression::Expression> exp) { stack_operand.push(exp); }
	bool empty() { return stack_operand.empty(); }

	PatternRecognition::Pattern<> topPattern() { return stack_pattern.top(); }
	void popPattern() { stack_pattern.pop(); }
	void pushPattern(const PatternRecognition::Pattern<>& exp) { stack_pattern.push(exp); }
	bool emptyPattern() { return stack_pattern.empty(); }

	AutoPointer<TreeExpression::Expression> evalTop() { return stack_operand.top()->eval(context); }
private:
	std::stack< AutoPointer<TreeExpression::Expression> > stack_operand;
	std::stack< PatternRecognition::Pattern<> > stack_pattern;
	CopyPointer<Context> context;
};

#endif
